# -*- coding: utf-8 -*-
# @Time: 2021/9/7 22:32
# @Author: yh
# @Remark: 执行任务
import logging
import os
import sys

from mxsoftpy.exception import DataError

base_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path.insert(0, base_dir)
sys.path.insert(0, os.path.dirname(base_dir))

from db.common.VideoManage.VideoQuality import TestItemsDB
from server.common.VideoManage.VideoQuality import VideoAnalyze
from utils.classes.custom_exception import ConnectionURLError
from utils.conf.mxconfig import MxConfig


class ImageDetection(object):

    def __init__(self, file_name: str):
        self.file_name = ''.join([MxConfig.TMP_DIR,file_name])
        self.test_items = TestItemsDB('TestItems').use_keys([])  # 所有检测项目
        self.__video_test_items = dict()  # 存放每个视频的检测项目，方便检测失败后生成数据

    def __exec_video(self):
        """
        异步执行多个video的检测
        """
        video_res = list()  # 存放视频检测数据

        video_analyze = VideoAnalyze()
        try:
            handle = video_analyze.fetch_file(self.file_name)  # 获取一帧图片
        except ConnectionURLError:
            logging.error('图片获取失败' )
            raise DataError('检测任务失败')

        test_res_list = [self.__exec_test(test_code, video_analyze, handle)
                         for test_code, item_info in self.test_items.items()]

        for test_code, item_info in self.test_items.items():
            if not isinstance(test_res_list[int(test_code)-1], float or int):

                video_res.append([
                                  ('test_code', test_code), ('test_value', -999),
                                  ('test_state', '检测失败'), ('test_name', item_info['name'])])
                continue

            else:
                expression = item_info['expression'].replace('value', str(test_res_list[int(test_code)-1])).replace(
                    'confidence', str(item_info['reference']))

                logging.debug('检测项目code：%s，判断评测值是否合规，执行判断表达式：%s' % (
                     test_code, expression))
                if eval(expression):
                    logging.debug('检测项目code：%s，不符合设定值，检测结果：故障' % (
                         test_code))
                    video_res.append([
                                      ('test_code', test_code),
                                      ('test_value', test_res_list[int(test_code)-1]), ('test_state', '故障'),
                                      ('test_name', item_info['name'])])
                else:
                    logging.debug('检测项目code：%s，符合设定值，检测结果：正常' % (
                        test_code))
                    video_res.append([
                                      ('test_code', test_code),
                                      ('test_value', round(test_res_list[int(test_code)-1], 5)),
                                      ('test_state', '正常'),
                                      ('test_name', item_info['name'])])

        video_analyze.pop_handle(handle)

        return video_res

    def __exec_test(self, test_code: str, instance: "VideoAnalyze", handle: object):
        """
        对每个video的检测项目异步执行检测
        :param instance: 检测类的实例，详情见VideoAnalyze类
        :param handle: 检测实例打开url后返回的句柄
        """
        try:
            res = instance.exec_fun(self.test_items[test_code]['func_name'], handle)
        except:
            return None
        logging.info('检测项目：%s，获取评检测值成功：%s' % (self.test_items[test_code]['name'], res))
        return res

    def start(self):
        """
        开始执行此条任务
        """
        # 执行
        video_res_list = self.__exec_video()
        for video_res in video_res_list:
            print(video_res)


if __name__ == '__main__':
    if len(sys.argv) == 2:
        task = ImageDetection(sys.argv[1])
        task.start()

